package com.jd.platform.sample4.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 通用属性名工具类，支持获取任意类的所有属性名字符串列表
 */
public class AttributeUtil {
    /**
     * 获取指定类的所有属性名（包括private修饰的属性）
     *
     * @param clazz 目标类的Class对象
     * @param <T>   类的类型
     * @return 属性名列表（按声明顺序排列）
     *
     * 使用举例：
     * List<String> produceAttrs = AttributeUtil.getAttributeNames(Produce.class);
     */
    public static <T> List<String> getAttributeNames(Class<T> clazz) {
        List<String> attributeNames = new ArrayList<>();

        // 获取类中所有声明的属性（包括private）
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            // 添加属性名到列表
            attributeNames.add(field.getName());
        }

        return attributeNames;
    }

    /**
     * 根据属性名获取对象的属性值（通过调用getter方法）
     *
     * @param obj       目标对象（如Produce实例）
     * @param attribute 属性名（如"name"）
     * @param <T>       对象类型
     * @return 属性值（如produce.getName()的返回值）
     * @throws Exception 反射调用异常（如属性不存在、方法调用失败等）
     *
     * 使用举例：
     * Object nameValue = AttributeUtil.getAttributeValue(produce,"name");
     */
    public static <T> Object getAttributeValue(T obj, String attribute) throws Exception {
        if (obj == null || attribute == null || attribute.isEmpty()) {
            throw new IllegalArgumentException("对象和属性名不能为空");
        }

        // 获取对象的类
        Class<?> clazz = obj.getClass();

        // 生成getter方法名（属性名首字母大写 + "get"前缀）
        // 例如：属性名"name" → 方法名"getName"
        String methodName = "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1);

        try {
            // 获取getter方法（无参数）
            Method getterMethod = clazz.getMethod(methodName);

            // 调用getter方法获取属性值
            return getterMethod.invoke(obj);
        } catch (NoSuchMethodException e) {
            // 处理boolean类型的特殊情况（getter方法可能以"is"开头，如isEnabled()）
            if (attribute.startsWith("is")) {
                methodName = attribute;
            } else {
                methodName = "is" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1);
            }
            Method isMethod = clazz.getMethod(methodName);
            return isMethod.invoke(obj);
        }
    }

    /**
     * 根据属性名列表获取对象中对应属性的值列表
     * @param obj 目标对象
     * @param keys 属性名列表（如["id", "name", "price"]）
     * @param <T> 对象类型
     * @return 值列表，与属性名列表顺序一一对应
     * @throws Exception 反射调用异常
     *
     * 使用举例：
     * List<String> values = AttributeUtil.getAttributeValues(produce, keys)
     */
    public static <T> List<String> getAttributeValues(T obj, List<String> keys) throws Exception {
        List<String> values = new ArrayList<>(keys.size());
        for (String key : keys) {
            // 调用已有的获取单个属性值方法，保证顺序一致
            String value = (String) getAttributeValue(obj, key);
            values.add(value);
        }
        return values;
    }

    /**
     * 根据属性名和值设置对象的属性（调用setter方法）
     *
     * @param obj       目标对象（如Produce实例）
     * @param attribute 属性名（如"name"）
     * @param value     要设置的值（如"苹果"）
     * @param <T>       对象类型
     * @throws Exception 反射调用异常（属性不存在、类型不匹配等）
     *
     * 使用举例：
     * AttributeUtil.setAttributeValue(produce, keys.get(i), values[i])
     */
    public static <T> void setAttributeValue(T obj, String attribute, Object value) throws Exception {
        if (obj == null || attribute == null || attribute.isEmpty()) {
            throw new IllegalArgumentException("对象和属性名不能为空");
        }

        // 获取对象的类
        Class<?> clazz = obj.getClass();
        // 生成setter方法名（属性名首字母大写 + "set"前缀）
        // 例如：属性名"name" → 方法名"setName"
        String methodName = "set" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1);

        // 获取属性类型（用于匹配setter方法的参数类型）
        Field field = clazz.getDeclaredField(attribute);
        Class<?> paramType = field.getType();

        // 如果value不为null，且类型不匹配，尝试进行类型转换（简单转换示例）
        if (value != null && !paramType.isInstance(value)) {
            value = convertValue(value, paramType);
        }

        // 获取setter方法（参数类型为属性的类型）
        Method setterMethod = clazz.getMethod(methodName, paramType);
        // 调用setter方法设置值
        setterMethod.invoke(obj, value);
    }

    /**
     * 简单的类型转换（支持常见基本类型和包装类）
     */
    private static Object convertValue(Object value, Class<?> targetType) {
        if (value == null) {
            return null;
        }

        String valueStr = value.toString();
        // 基本类型及包装类转换
        if (targetType == int.class || targetType == Integer.class) {
            return Integer.parseInt(valueStr);
        } else if (targetType == long.class || targetType == Long.class) {
            return Long.parseLong(valueStr);
        } else if (targetType == double.class || targetType == Double.class) {
            return Double.parseDouble(valueStr);
        } else if (targetType == boolean.class || targetType == Boolean.class) {
            return Boolean.parseBoolean(valueStr);
        } else if (targetType == String.class) {
            return valueStr;
        }
        // 其他类型不支持转换，直接返回原值（可能导致调用失败）
        return value;
    }
}
